#include <iostream>
#include <sstream>
#include <string>
#include <assert.h>
#include "status.hxx"
#include "util/fs.hxx"
#include "util/io.hxx"
#include "util/common.hxx"

static utility::PerformanceMeasure perf("perf");

std::string path;

PosixMmapSequentialWriter* w = NULL;
PosixSequentialReader* r = NULL;

void init() {

    DbStatus ret;

    w = new PosixMmapSequentialWriter(path, getpagesize(), 1024);
    ret = w->init();
    if(!ret.isok()) {std::cout<<ret.msg()<<"\n";return;}

    r = new PosixSequentialReader(path);
    ret = r->init();
    if(!ret.isok()) {std::cout<<ret.msg()<<"\n";return;}    
}

void clean() {
    
    DbStatus ret;

    ret = FsUtility::deleteFile(path);
    if(!ret.isok()) {std::cout<<"clean file: "<<ret.msg()<<"\n";return;}

    delete w; delete r;
    w = NULL; r = NULL;
}

//small record, write n records
int testOSBuffer() {
    
    DbStatus ret;

    init();

    char buf[256];
    int m = 1000;
    int n = 4*4*1024;

    perf.start();

    //write

    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < n; ++j) {
            snprintf(buf, 256, "%d", j);

            ret = w->append(buf, 256);
            if(!ret.isok()) {std::cout<<ret.msg()<<"\n";return -1;}
        }

        w->flush();
    }

    w->close();

    perf.end();

    std::cout<<perf.avg()<<"\n";

    clean();

    return 0;
}

int testAppBuffer() {
    
    DbStatus ret;

    init();

    char buf[256];
    int m = 1000;
    int n = 4*4*1024;

    char *bigbuf = new char[n*256];

    perf.start();

    //write

    for(int i = 0; i < m; ++i) {
        for(int pos = 0; pos < n; pos+=256) {
            snprintf(buf, 256, "%d", pos);
            memcpy(bigbuf+pos, buf, 256);
        }

        ret = w->append(bigbuf, n*256);
        if(!ret.isok()) {std::cout<<ret.msg()<<"\n";return -1;}
        w->flush();
    }

    w->close();
    
    perf.end();

    clean();

    return 0;

}
    
int main(int argc, char** argv) {

    path = std::string(argv[1]);
    if(argv[2][0] == '0') testOSBuffer();
    else testAppBuffer();
}

